﻿using System.Xml;

namespace AppDesigner.XamlDom
{
    /// <summary>
    /// XmlDocument that has PositionInfo
    /// </summary>
    public class PositionXmlDocument : XmlDocument
    {
        private IXmlLineInfo _xmlLineInfo;

        #region Override

        public override XmlElement CreateElement(string prefix, string localName, string namespaceURI)
        {
            return new PositionXmlElement(prefix, localName, namespaceURI, this, _xmlLineInfo);
        }

        public override XmlAttribute CreateAttribute(string prefix, string localName, string namespaceURI)
        {
            return new PositionXmlAttribute(prefix, localName, namespaceURI, this, _xmlLineInfo);
        }

        /// <summary>
        /// 重写load方法
        /// 将行列信息的XamlTextReader加载进来
        /// </summary>
        /// <param name="reader"></param>
        public override void Load(XmlReader reader)
        {
            _xmlLineInfo = (IXmlLineInfo)reader;
            try
            {
                base.Load(reader);
            }
            finally
            {
                _xmlLineInfo = null;
            }
        }

        #endregion
        
    }

    public class PositionXmlElement : XmlElement, IXmlLineInfo
    {

        #region Fields

        private bool hasLineInfo;
        private int lineNumber;
        private int linePosition;

        #endregion

        #region Constructor

        public PositionXmlElement(string prefix, string localName, string namespaceURI, XmlDocument doc,IXmlLineInfo xmlLineInfo)
            : base(prefix, localName, namespaceURI, doc)
        {
            if (xmlLineInfo != null)
            {
                hasLineInfo = true;
                lineNumber = xmlLineInfo.LineNumber;
                linePosition = xmlLineInfo.LinePosition;
            }
        }

        #endregion

        #region Property&Method

        public bool HasLineInfo()
        {
            return hasLineInfo;
        }

        public int LineNumber
        {
            get { return lineNumber; }
        }

        public int LinePosition
        {
            get { return linePosition; }
        }

        #endregion
       
    }

    public class PositionXmlAttribute : XmlAttribute, IXmlLineInfo
    {
        #region Fields

        private bool hasLineInfo;
        private int lineNumber;
        private int linePosition;

        #endregion

        #region Constructor

        public PositionXmlAttribute(string prefix, string localName, string namespaceURI, XmlDocument doc, IXmlLineInfo xmlLineInfo)
            : base(prefix, localName, namespaceURI, doc)
        {
            if (xmlLineInfo != null)
            {
                hasLineInfo = true;
                lineNumber = xmlLineInfo.LineNumber;
                linePosition = xmlLineInfo.LinePosition;
            }
        }

        #endregion

        #region Property&Method

        public bool HasLineInfo()
        {
            return hasLineInfo;
        }

        public int LineNumber
        {
            get { return lineNumber; }
        }

        public int LinePosition
        {
            get { return linePosition; }
        }

        #endregion
        
    }

}
